package cn.likun.kit.placeholder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.likun.kit.validate.ValidateCommons;

/**
 * <p>占位符替换工具类</p>
 */
public class PlaceholderCommons {
	
	public static final String PLACEHOLDER_PREFFIX = "#[";
	public static final String PLACEHOLDER_SUFFIX = "]";
	
	private static final String innerExpr = "\\#\\[[0-9a-zA-Z\\.\\+\\-\\_]+\\]";
	
	/**
	 * <p>判断key是否为内置的占位符</p>
	 * @param key
	 * @return
	 */
	public static boolean isInnerExpr(String key) {
		return ValidateCommons.matchRule(key, innerExpr);
	}
	/**
	 * <p>获取内置的占位符</p>
	 * @param key
	 * @return
	 */
	public static String getInnerKey(String key) {
		if (isInnerExpr(key)) {
			return key.substring(PLACEHOLDER_PREFFIX.length(), key.length() - PLACEHOLDER_SUFFIX.length()).trim();
		}
		return null;
	}
	/**
	 * <p>方法名：getInnerKeys</p>
	 * <p>描述：获取字符串中所有内置的占位符 key</p>
	 * @param str 带有占位符的字符串
	 * @return innerKey 集合
	 */
	public static List<String> getInnerKeys(String str) {
		List<String> innerKeys = new ArrayList<String>();
		Pattern keyPattern = Pattern.compile(innerExpr);
		Matcher keyMatcher = keyPattern.matcher(str);
		while (keyMatcher.find()) {
			String key  = keyMatcher.group();
			String innerKey = key.substring(PLACEHOLDER_PREFFIX.length(),key.length() - PLACEHOLDER_SUFFIX.length()).trim();
			innerKeys.add(innerKey);
			str = keyMatcher.replaceFirst("");
			keyMatcher = keyPattern.matcher(str);
		}
		return innerKeys;
	}
	/**
	 * <p>方法名：replacePlaceholder</p>
	 * <p>描述：根据传入匹配正则表达式的替换占位符</p>
	 * @param expr 匹配正则表达式
	 * @param str 带有占位符的字符串
	 * @param cutPrefix 截取开头位
	 * @param cutSuffix 截取末尾位
	 * @param params key > value 映射
	 * @return 替换占位符后的字符串
	 */
	public static String replacePlaceholder(String expr, String str,int cutPrefix, int cutSuffix, Map<String,?> params) {
		Pattern keyPattern = Pattern.compile(expr);
		Matcher keyMatcher = keyPattern.matcher(str);
		while (keyMatcher.find()) {
			String key = keyMatcher.group();
			String innerKey = key.substring(cutPrefix, key.length() - cutSuffix).trim();
			Object innerValue = params.get(innerKey);
			String value = "";
			if (ValidateCommons.isNotEmpty(innerValue)) {
				value = innerValue.toString();
				//处理$ 特殊字符
				value = value.replace("$", "\\$");
			}
			str = keyMatcher.replaceFirst(value);
			keyMatcher = keyPattern.matcher(str);
		}
		return str ;
	}
	/**
	 * <p>方法名：replacePlaceholder</p>
	 * <p>描述：可通过 #[key] 的方式定义替换占位符</p>
	 * @param str 带有占位符的字符串
	 * @param params key > value 映射
	 * @return 替换占位符后的字符串
	 */
	public static String replacePlaceholder(String str, Map<String,?> params) {
		return replacePlaceholder(innerExpr, str, PLACEHOLDER_PREFFIX.length(), PLACEHOLDER_SUFFIX.length(), params);
	}
	/**
	 * <p>方法名：reversalPlaceholder</p>
	 * <p>描述：根据占位符规则反转解析字符串，此方法只能解析分隔符规则的字符串</p>
	 * @param expr 匹配正则表达式
	 * @param rule 带有占位符的字符串
	 * @param cutPrefix 截取开头位
	 * @param cutSuffix 截取末尾位
	 * @param str 需要反转解析的字符串
	 * @return key > value 映射
	 */
	public static Map<String,String> reversalPlaceholder(String expr, String rule, int cutPrefix, int cutSuffix, String str) {
		Map<String,String> keyMap = new HashMap<String,String>();
		Map<String,String> valueMap = new HashMap<String,String>();
		Pattern keyPattern = Pattern.compile(expr);
		Matcher keyMatcher = keyPattern.matcher(rule);
		int index = 0;
		while (keyMatcher.find()) {
			index++;
			String tempStr = String.valueOf(index);
			String key = keyMatcher.group();
			String innerKey = key.substring(cutPrefix, key.length() - cutSuffix).trim();
			keyMap.put(tempStr, innerKey);
			rule = keyMatcher.replaceFirst(tempStr);
			keyMatcher = keyPattern.matcher(rule);
		}
		for (int i = 1; i <= index; i++) {
			String start = String.valueOf(i);
			String end = String.valueOf(i + 1);
			int startIndex = rule.indexOf(start) + 1;
			int endIndex = rule.indexOf(end);
			if (i == index) {
				endIndex = rule.length();
			}
			String separate = rule.substring(startIndex,endIndex);
			int strIndex = str.indexOf(separate);
			if (strIndex == 0 && ValidateCommons.isEmpty(separate)) {
				return valueMap;
			}
			String value = str.substring(0, strIndex);
			if (i == index && strIndex == 0) {
				value = str;
			}
			valueMap.put(keyMap.get(start), value);
			rule = rule.substring(endIndex);
			str = str.substring(strIndex + 1);
		}
		return valueMap;
	}
	
	/**
	 * <p>方法名：reversalPlaceholder</p>
	 * <p>描述：根据占位符规则反转解析字符串，此方法只能解析分隔符规则的字符串</p>
	 * @param rule 带有占位符的字符串
	 * @param str 需要反转解析的字符串
	 * @return key > value 映射
	 */
	public static Map<String, String> reversalPlaceholder(String rule, String str) {
		return reversalPlaceholder(innerExpr, rule, PLACEHOLDER_PREFFIX.length(), PLACEHOLDER_SUFFIX.length(), str);
	}
	
	
	
	
	
	
	
	
	
	
	
}



















